home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / emula / arosdv19.lha / AROS / config / linux / intuition_driver.c < prev    next >
C/C++ Source or Header  |  1996-11-08  |  27KB  |  1,242 lines

  1. #include <X11/Xlib.h>
  2. #include <X11/Xutil.h>
  3. #include <X11/cursorfont.h>
  4. #include <X11/keysym.h>
  5.  
  6. #undef CurrentTime /* Defined by X.h */
  7. #define XCurrentTime 0L
  8.  
  9. #define DEBUG_FreeMem 1
  10.  
  11. #include <stdlib.h>
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <exec/memory.h>
  15. #include <dos/dos.h>
  16. #include <utility/tagitem.h>
  17. #include <intuition/cghooks.h>
  18. #include <intuition/gadgetclass.h>
  19. #include <clib/exec_protos.h>
  20. #include <clib/intuition_protos.h>
  21. #include <clib/graphics_protos.h>
  22. #include <clib/aros_protos.h>
  23. #include <clib/alib_protos.h>
  24. #include "intuition_intern.h"
  25. #include "gadgets.h"
  26. #include "propgadgets.h"
  27.  
  28. static struct IntuitionBase * IntuiBase;
  29.  
  30. extern Display * sysDisplay;
  31. extern long sysCMap[];
  32. extern unsigned long sysPlaneMask;
  33. extern Cursor sysCursor;
  34.  
  35. Display * GetSysDisplay (void);
  36. int      GetSysScreen (void);
  37. extern void SetGC (struct RastPort * rp, GC gc);
  38. extern GC GetGC (struct RastPort * rp);
  39. extern void SetXWindow (struct RastPort * rp, int win);
  40.  
  41. static int MyErrorHandler (Display *, XErrorEvent *);
  42. static int MySysErrorHandler (Display *);
  43.  
  44. #define DEBUG    0
  45. #define DEBUG_ProcessXEvents    0
  46.  
  47. #if DEBUG
  48. #   define D(x)     x
  49. #else
  50. #   define D(x)     /* eps */
  51. #endif
  52.  
  53. #if DEBUG_ProcessXEvents
  54. #   define Dipxe(x) x
  55. #else
  56. #   define Dipxe(x) /* eps */
  57. #endif
  58.  
  59. #if DEBUG_OpenWindow
  60. #   define Diow(x) x
  61. #else
  62. #   define Diow(x) /* eps */
  63. #endif
  64.  
  65. #if DEBUG_CloseWindow
  66. #   define Dicw(x) x
  67. #else
  68. #   define Dicw(x) /* eps */
  69. #endif
  70.  
  71. #define bug        kprintf
  72.  
  73. struct IntWindow
  74. {
  75.     struct Window iw_Window;
  76.     int       iw_XWindow;
  77.     Region      iw_Region;
  78. };
  79.  
  80. struct _keytable
  81. {
  82.     KeySym keysym;
  83.     WORD   amiga;
  84.     UWORD  amiga_qual;
  85.     char * normal,
  86.      * shifted;
  87.     ULONG  keycode;
  88. }
  89. keytable[] =
  90. {
  91.     {XK_Return,     0x44, 0,              "\012",   "\012", 0 },
  92.     {XK_Right,        0x4e, 0,              "\233C",  "\233 A", 0 },
  93.     {XK_Up,        0x4c, 0,              "\233A",  "\233T",0 },
  94.     {XK_Left,        0x4f, 0,              "\233D",  "\233 @",0 },
  95.     {XK_Down,        0x4d, 0,              "\233B",  "\233S",0 },
  96.     {XK_Help,        0x5f, 0,              "\233?~", "\233?~",0 },
  97.     {XK_KP_Enter,    0x43, IEQUALIFIER_NUMERICPAD, "\015",   "\015",0 },
  98.     {XK_KP_Separator,    0x3c, IEQUALIFIER_NUMERICPAD, ".",      ".",0 },
  99.     {XK_KP_Subtract,    0x4a, IEQUALIFIER_NUMERICPAD, "-",      "-",0 },
  100.     {XK_KP_Decimal,    0x3c, IEQUALIFIER_NUMERICPAD, ".",      ".",0 },
  101.     {XK_KP_0,        0x0f, IEQUALIFIER_NUMERICPAD, "0",      "0",0 },
  102.     {XK_KP_1,        0x1d, IEQUALIFIER_NUMERICPAD, "1",      "1",0 },
  103.     {XK_KP_2,        0x1e, IEQUALIFIER_NUMERICPAD, "2",      "2",0 },
  104.     {XK_KP_3,        0x1f, IEQUALIFIER_NUMERICPAD, "3",      "3",0 },
  105.     {XK_KP_4,        0x2d, IEQUALIFIER_NUMERICPAD, "4",      "4",0 },
  106.     {XK_KP_5,        0x2e, IEQUALIFIER_NUMERICPAD, "5",      "5",0 },
  107.     {XK_KP_6,        0x2f, IEQUALIFIER_NUMERICPAD, "6",      "6",0 },
  108.     {XK_KP_7,        0x3d, IEQUALIFIER_NUMERICPAD, "7",      "7",0 },
  109.     {XK_KP_8,        0x3e, IEQUALIFIER_NUMERICPAD, "8",      "8",0 },
  110.     {XK_KP_9,        0x3f, IEQUALIFIER_NUMERICPAD, "9",      "9",0 },
  111.     {XK_F1,        0x50, 0,              "\2330~", "\23310~",0 },
  112.     {XK_F2,        0x51, 0,              "\2331~", "\23311~",0 },
  113.     {XK_F3,        0x52, 0,              "\2332~", "\23312~",0 },
  114.     {XK_F4,        0x53, 0,              "\2333~", "\23313~",0 },
  115.     {XK_F5,        0x54, 0,              "\2334~", "\23314~",0 },
  116.     {XK_F6,        0x55, 0,              "\2335~", "\23315~",0 },
  117.     {XK_F7,        0x56, 0,              "\2336~", "\23316~",0 },
  118.     {XK_F8,        0x57, 0,              "\2337~", "\23317~",0 },
  119.     {XK_F9,        0x58, 0,              "\2338~", "\23318~",0 },
  120.     {XK_F10,        0x59, 0,              "\2339~", "\23319~",0 },
  121.     {0, -1, 0, },
  122. };
  123.  
  124. #define SHIFT    (IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT)
  125. #define LALT    IEQUALIFIER_LALT
  126. #define RALT    IEQUALIFIER_RALT
  127. #define CTRL    IEQUALIFIER_CONTROL
  128. #define CAPS    IEQUALIFIER_CAPSLOCK
  129.  
  130.  
  131. static int MyErrorHandler (Display * display, XErrorEvent * errevent)
  132. {
  133.     char buffer[256];
  134.  
  135.     XGetErrorText (display, errevent->error_code, buffer, sizeof (buffer));
  136.  
  137.     fprintf (stderr
  138.     , "XError %d (Major=%d, Minor=%d)\n%s\n"
  139.     , errevent->error_code
  140.     , errevent->request_code
  141.     , errevent->minor_code
  142.     , buffer
  143.     );
  144.     fflush (stderr);
  145.  
  146.     exit (10);
  147. }
  148.  
  149. static int MySysErrorHandler (Display * display)
  150. {
  151.     perror ("X11-Error");
  152.     fflush (stderr);
  153.  
  154.     exit (10);
  155. }
  156.  
  157. int intui_init (struct IntuitionBase * IntuitionBase)
  158. {
  159.     int t;
  160.  
  161.     if (!sysDisplay)
  162.     return False;
  163.  
  164.     for (t=0; keytable[t].amiga != -1; t++)
  165.     keytable[t].keycode = XKeysymToKeycode (sysDisplay,
  166.         keytable[t].keysym);
  167.  
  168.     XSetErrorHandler (MyErrorHandler);
  169.     XSetIOErrorHandler (MySysErrorHandler);
  170.  
  171.     /* TODO this is a hack */
  172.     IntuiBase = IntuitionBase;
  173.  
  174.     return True;
  175. }
  176.  
  177. int intui_open (struct IntuitionBase * IntuitionBase)
  178. {
  179.     if (GetPrivIBase(IntuitionBase)->WorkBench)
  180.     {
  181.     GetPrivIBase(IntuitionBase)->WorkBench->Width =
  182.         DisplayWidth (GetSysDisplay (), GetSysScreen ());
  183.     GetPrivIBase(IntuitionBase)->WorkBench->Height =
  184.         DisplayHeight (GetSysDisplay (), GetSysScreen ());
  185.     }
  186.  
  187.     return True;
  188. }
  189.  
  190. void intui_close (struct IntuitionBase * IntuitionBase)
  191. {
  192.     return;
  193. }
  194.  
  195. void intui_expunge (struct IntuitionBase * IntuitionBase)
  196. {
  197.     return;
  198. }
  199.  
  200. void intui_SetWindowTitles (struct Window * win, UBYTE * text, UBYTE * screen)
  201. {
  202.     XSizeHints hints;
  203.     struct IntWindow * w;
  204.  
  205.     w = (struct IntWindow *)win;
  206.  
  207.     hints.x     = win->LeftEdge;
  208.     hints.y     = win->TopEdge;
  209.     hints.width  = win->Width;
  210.     hints.height = win->Height;
  211.     hints.flags  = PPosition | PSize;
  212.  
  213.     if (screen == (UBYTE *)~0L)
  214.     screen = "Workbench 3.1";
  215.     else if (!screen)
  216.     screen = "";
  217.  
  218.     if (text == (UBYTE *)~0LL)
  219.     text = win->Title;
  220.     else if (!text)
  221.     text = "";
  222.  
  223.     XSetStandardProperties (sysDisplay, w->iw_XWindow, text, screen,
  224.         None, NULL, 0, &hints);
  225. }
  226.  
  227. int intui_GetWindowSize (void)
  228. {
  229.     return sizeof (struct IntWindow);
  230. }
  231.  
  232. #define IW(w)   ((struct IntWindow *)w)
  233.  
  234. int intui_OpenWindow (struct Window * w,
  235.     struct IntuitionBase * IntuitionBase)
  236. {
  237.     XSetWindowAttributes winattr;
  238.  
  239.     if (!GetGC (IW(w)->iw_Window.RPort))
  240.     return FALSE;
  241.  
  242.     winattr.event_mask = 0;
  243.  
  244.     if ((IW(w)->iw_Window.Flags & WFLG_REFRESHBITS) == WFLG_SMART_REFRESH)
  245.     {
  246.     winattr.backing_store = Always;
  247.     }
  248.     else
  249.     {
  250.     winattr.backing_store = NotUseful;
  251.     winattr.event_mask |= ExposureMask;
  252.     }
  253.  
  254.     if ((IW(w)->iw_Window.Flags & WFLG_RMBTRAP)
  255.     || IW(w)->iw_Window.IDCMPFlags
  256.         & (IDCMP_MOUSEBUTTONS
  257.         | IDCMP_GADGETDOWN
  258.         | IDCMP_GADGETUP
  259.         | IDCMP_MENUPICK
  260.         )
  261.     || IW(w)->iw_Window.FirstGadget
  262.     )
  263.     winattr.event_mask |= ButtonPressMask | ButtonReleaseMask;
  264.  
  265.     if (IW(w)->iw_Window.IDCMPFlags & IDCMP_REFRESHWINDOW)
  266.     winattr.event_mask |= ExposureMask;
  267.  
  268.     if (IW(w)->iw_Window.IDCMPFlags & IDCMP_MOUSEMOVE
  269.     || IW(w)->iw_Window.FirstGadget
  270.     )
  271.     winattr.event_mask |= PointerMotionMask;
  272.  
  273.     if (IW(w)->iw_Window.IDCMPFlags & (IDCMP_RAWKEY | IDCMP_VANILLAKEY))
  274.     winattr.event_mask |= KeyPressMask | KeyReleaseMask;
  275.  
  276.     if (IW(w)->iw_Window.IDCMPFlags & IDCMP_ACTIVEWINDOW)
  277.     winattr.event_mask |= EnterWindowMask;
  278.  
  279.     if (IW(w)->iw_Window.IDCMPFlags & IDCMP_INACTIVEWINDOW)
  280.     winattr.event_mask |= LeaveWindowMask;
  281.  
  282.     /* Always show me if the window has changed */
  283.     winattr.event_mask |= StructureNotifyMask;
  284.  
  285.     /* TODO IDCMP_SIZEVERIFY IDCMP_DELTAMOVE */
  286.  
  287.     winattr.cursor = sysCursor;
  288.     winattr.save_under = True;
  289.     winattr.background_pixel = sysCMap[0];
  290.  
  291.     IW(w)->iw_XWindow = XCreateWindow (GetSysDisplay ()
  292.     , DefaultRootWindow (GetSysDisplay ())
  293.     , IW(w)->iw_Window.LeftEdge
  294.     , IW(w)->iw_Window.TopEdge
  295.     , IW(w)->iw_Window.Width
  296.     , IW(w)->iw_Window.Height
  297.     , 5 /* BorderWidth */
  298.     , DefaultDepth (GetSysDisplay (), GetSysScreen ())
  299.     , InputOutput
  300.     , DefaultVisual (GetSysDisplay (), GetSysScreen ())
  301.     , CWBackingStore
  302.         | CWCursor
  303.         | CWSaveUnder
  304.         | CWEventMask
  305.         | CWBackPixel
  306.     , &winattr
  307.     );
  308.  
  309.     SetXWindow (IW(w)->iw_Window.RPort, IW(w)->iw_XWindow);
  310.  
  311.     IW(w)->iw_Region = XCreateRegion ();
  312.  
  313.     if (!IW(w)->iw_Region)
  314.     {
  315.     XDestroyWindow (sysDisplay, IW(w)->iw_XWindow);
  316.     return FALSE;
  317.     }
  318.  
  319.     XMapRaised (sysDisplay, IW(w)->iw_XWindow);
  320.  
  321.     /* Show window *now* */
  322.     XFlush (sysDisplay);
  323.  
  324.     Diow(bug("Opening Window %p (X=%ld)\n", iw, IW(w)->iw_XWindow));
  325.  
  326.     return 1;
  327. }
  328.  
  329. void intui_CloseWindow (struct Window * w,
  330.         struct IntuitionBase * IntuitionBase)
  331. {
  332.     Dicw(bug("Closing Window %p (X=%ld)\n", w, IW(w)->iw_XWindow));
  333.  
  334.     XDestroyWindow (sysDisplay, IW(w)->iw_XWindow);
  335.  
  336.     XDestroyRegion (IW(w)->iw_Region);
  337.  
  338.     XSync (sysDisplay, FALSE);
  339. }
  340.  
  341. void intui_WindowToFront (struct Window * window)
  342. {
  343.     XRaiseWindow (sysDisplay, IW(window)->iw_XWindow);
  344. }
  345.  
  346. void intui_WindowToBack (struct Window * window)
  347. {
  348.     XLowerWindow (sysDisplay, IW(window)->iw_XWindow);
  349. }
  350.  
  351. long StateToQualifier (unsigned long state)
  352. {
  353.     long result;
  354.  
  355.     result = 0;
  356.  
  357.     if (state & ShiftMask)
  358.     result |= SHIFT;
  359.  
  360.     if (state & ControlMask)
  361.     result |= CTRL;
  362.  
  363.     if (state & LockMask)
  364.     result |= CAPS;
  365.  
  366.     if (state & Mod2Mask) /* Right Alt */
  367.     result |= LALT;
  368.  
  369.     if (state & 0x2000) /* Mode switch */
  370.     result |= RALT;
  371.  
  372.     if (state & Mod1Mask) /* Left Alt */
  373.     result |= AMIGAKEYS;
  374.  
  375.     if (state & Button1Mask)
  376.     result |= IEQUALIFIER_LEFTBUTTON;
  377.  
  378.     if (state & Button2Mask)
  379.     result |= IEQUALIFIER_RBUTTON;
  380.  
  381.     if (state & Button3Mask)
  382.     result |= IEQUALIFIER_MIDBUTTON;
  383.  
  384.     return (result);
  385. } /* StateToQualifier */
  386.  
  387. long XKeyToAmigaCode (XKeyEvent * xk)
  388. {
  389.     char buffer[10];
  390.     KeySym ks;
  391.     int count;
  392.     long result;
  393.     short t;
  394.  
  395.     result = StateToQualifier (xk->state) << 16L;
  396.  
  397.     xk->state = 0;
  398.     count = XLookupString (xk, buffer, 10, &ks, NULL);
  399.  
  400.     for (t=0; keytable[t].amiga != -1; t++)
  401.     {
  402.     if (ks == keytable[t].keycode)
  403.     {
  404.         result |= (keytable[t].amiga_qual << 16) | keytable[t].amiga;
  405.         return (result);
  406.     }
  407.     }
  408.  
  409.     result |= xk->keycode & 0xffff;
  410.  
  411.     return (result);
  412. } /* XKeyToAmigaCode */
  413.  
  414. void intui_SizeWindow (struct Window * win, long dx, long dy)
  415. {
  416.     XResizeWindow (sysDisplay
  417.     , ((struct IntWindow *)win)->iw_XWindow
  418.     , win->Width + dx
  419.     , win->Height + dy
  420.     );
  421. }
  422.  
  423. void intui_ActivateWindow (struct Window * win)
  424. {
  425.     XSetInputFocus (sysDisplay, IW(win)->iw_XWindow, RevertToNone, XCurrentTime);
  426. }
  427.  
  428. LONG intui_RawKeyConvert (struct InputEvent * ie, STRPTR buf,
  429.     LONG size, struct KeyMap * km)
  430. {
  431.     XKeyEvent xk;
  432.     char * ptr;
  433.     int t;
  434.  
  435.     ie->ie_Code &= 0x7fff;
  436.  
  437.     for (t=0; keytable[t].amiga != -1; t++)
  438.     {
  439.     if (ie->ie_Code == keytable[t].keycode)
  440.     {
  441.         if (ie->ie_Qualifier & SHIFT)
  442.         ptr = keytable[t].shifted;
  443.         else
  444.         ptr = keytable[t].normal;
  445.  
  446.         t = strlen(ptr);
  447.         if (t > size)
  448.         t = size;
  449.  
  450.         strncpy (buf, ptr, t);
  451.  
  452.         goto ende;
  453.     }
  454.     }
  455.  
  456.     xk.keycode = ie->ie_Code;
  457.     xk.display = sysDisplay;
  458.     xk.state = 0;
  459.  
  460.     if (ie->ie_Qualifier & SHIFT)
  461.     xk.state |= ShiftMask;
  462.  
  463.     if (ie->ie_Qualifier & CTRL)
  464.     xk.state |= ControlMask;
  465.  
  466.     if (ie->ie_Qualifier & CAPS)
  467.     xk.state |= LockMask;
  468.  
  469.     if (ie->ie_Qualifier & RALT)
  470.     xk.state |= 0x2000;
  471.  
  472.     if (ie->ie_Qualifier & LALT)
  473.     xk.state |= Mod2Mask;
  474.  
  475.     if (ie->ie_Qualifier & AMIGAKEYS)
  476.     xk.state |= Mod1Mask;
  477.  
  478.     if (ie->ie_Qualifier & IEQUALIFIER_LEFTBUTTON)
  479.     xk.state |= Button1Mask;
  480.  
  481.     if (ie->ie_Qualifier & IEQUALIFIER_MIDBUTTON)
  482.     xk.state |= Button2Mask;
  483.  
  484.     if (ie->ie_Qualifier & IEQUALIFIER_RBUTTON)
  485.     xk.state |= Button3Mask;
  486.  
  487.     t = XLookupString (&xk, buf, size, NULL, NULL);
  488.  
  489.     if (!*buf && t == 1) t = 0;
  490.     if (!t) *buf = 0;
  491.  
  492. ende:
  493. /*
  494.     printf ("RawKeyConvert: In %02x %04x %04x Out : %d cs %02x '%c'\n",
  495.         ie->ie_Code, ie->ie_Qualifier, xk.state, t, (ubyte)*buf,
  496.         (ubyte)*buf);
  497. */
  498.  
  499.     return (t);
  500. } /* intui_RawKeyConvert */
  501.  
  502. void intui_BeginRefresh (struct Window * win,
  503.     struct IntuitionBase * IntuitionBase)
  504. {
  505.    /* Restrict rendering to a region */
  506.    XSetRegion (sysDisplay, GetGC(IW(win)->iw_Window.RPort), IW(win)->iw_Region);
  507. } /* intui_BeginRefresh */
  508.  
  509. void intui_EndRefresh (struct Window * win, BOOL free,
  510.     struct IntuitionBase * IntuitionBase)
  511. {
  512.    Region region;
  513.    XRectangle rect;
  514.  
  515.    /* Zuerst alte Region freigeben (Speicher sparen) */
  516.    if (free)
  517.    {
  518.       XDestroyRegion (IW(win)->iw_Region);
  519.  
  520.       IW(win)->iw_Region = XCreateRegion ();
  521.    }
  522.  
  523.    /* Dann loeschen wir das ClipRect wieder indem wir ein neues
  524.       erzeugen, welches das ganze Fenster ueberdeckt. */
  525.    region = XCreateRegion ();
  526.  
  527.    rect.x      = 0;
  528.    rect.y      = 0;
  529.    rect.width  = IW(win)->iw_Window.Width;
  530.    rect.height = IW(win)->iw_Window.Height;
  531.  
  532.    XUnionRectWithRegion (&rect, region, region);
  533.  
  534.    /* und setzen */
  535.    XSetRegion (sysDisplay, GetGC(IW(win)->iw_Window.RPort), region);
  536. } /* intui_EndRefresh */
  537.  
  538.  
  539. #define ADDREL(gad,flag,w,field) ((gad->Flags & (flag)) ? w->field : 0)
  540. #define GetLeft(gad,w)           (ADDREL(gad,GFLG_RELRIGHT,w,Width)   + gad->LeftEdge)
  541. #define GetTop(gad,w)            (ADDREL(gad,GFLG_RELBOTTOM,w,Height) + gad->TopEdge)
  542. #define GetWidth(gad,w)          (ADDREL(gad,GFLG_RELWIDTH,w,Width)   + gad->Width)
  543. #define GetHeight(gad,w)         (ADDREL(gad,GFLG_RELHEIGHT,w,Height) + gad->Height)
  544.  
  545. #define InsideGadget(w,gad,x,y)   \
  546.         ((x) >= GetLeft(gad,w) && (y) >= GetTop(gad,w) \
  547.         && (x) < GetLeft(gad,w) + GetWidth(gad,w) \
  548.         && (y) < GetTop(gad,w) + GetHeight(gad,w))
  549.  
  550.  
  551. struct Gadget * FindGadget (struct Window * window, int x, int y,
  552.             struct GadgetInfo * gi)
  553. {
  554.     struct Gadget * gadget;
  555.     struct gpHitTest gpht;
  556.     int gx, gy;
  557.  
  558.     gpht.MethodID     = GM_HITTEST;
  559.     gpht.gpht_GInfo   = gi;
  560.     gpht.gpht_Mouse.X = x;
  561.     gpht.gpht_Mouse.Y = y;
  562.  
  563.     for (gadget=window->FirstGadget; gadget; gadget=gadget->NextGadget)
  564.     {
  565.     if ((gadget->GadgetType & GTYP_GTYPEMASK) != GTYP_CUSTOMGADGET)
  566.     {
  567.         gx = x - GetLeft(gadget,window);
  568.         gy = y - GetTop(gadget,window);
  569.  
  570.         if (gx >= 0
  571.         && gy >= 0
  572.         && gx < GetWidth(gadget,window)
  573.         && gy < GetHeight(gadget,window)
  574.         )
  575.         break;
  576.     }
  577.     else
  578.     {
  579.         if (DoMethodA ((Object *)gadget, (Msg)&gpht) == GMR_GADGETHIT)
  580.         break;
  581.     }
  582.     }
  583.  
  584.     return gadget;
  585. } /* FindGadget */
  586.  
  587. #undef IntuitionBase
  588. #define IntuitionBase IntuiBase
  589.  
  590. void intui_ProcessEvents (void)
  591. {
  592.     struct IntuiMessage * im;
  593.     struct Window    * w;
  594.     struct IntWindow    * iw;
  595.     struct Gadget    * gadget;
  596.     struct MsgPort    * intuiReplyPort;
  597.     struct Screen    * screen;
  598.     struct GadgetInfo    * gi;
  599.     char * ptr;
  600.     int    mpos_x, mpos_y;
  601.     int    wait;
  602.     XEvent event;
  603.     ULONG  lock;
  604.  
  605.     intuiReplyPort = CreateMsgPort ();
  606.     wait = 0;
  607.  
  608.     gi = AllocMem (sizeof (struct GadgetInfo), MEMF_ANY|MEMF_CLEAR);
  609.  
  610.     for (;;)
  611.     {
  612.     im = NULL;
  613.     w = NULL;
  614.  
  615.     while (XPending (sysDisplay))
  616.     {
  617.         XNextEvent (sysDisplay, &event);
  618.  
  619.         Dipxe(bug("Got Event for X=%d\n", event.xany.window));
  620.  
  621.         if (event.type == MappingNotify)
  622.         {
  623.         XRefreshKeyboardMapping ((XMappingEvent*)&event);
  624.         continue;
  625.         }
  626.  
  627.         lock = LockIBase (0L);
  628.  
  629.         /* Search window */
  630.         for (screen=IntuitionBase->FirstScreen; screen; screen=screen->NextScreen)
  631.         {
  632.         for (w=screen->FirstWindow; w; w=w->NextWindow)
  633.         {
  634.             if (((struct IntWindow *)w)->iw_XWindow == event.xany.window)
  635.             break;
  636.         }
  637.  
  638.         if (w)
  639.             break;
  640.         }
  641.  
  642.  
  643.         if (w)
  644.         {
  645.         /* Make sure that no one closes the window while we work on it */
  646.         w->MoreFlags |= EWFLG_DELAYCLOSE;
  647.  
  648.         Dipxe(bug("X=%d is asocciated with Window %p\n",
  649.             event.xany.window,
  650.             w
  651.         ));
  652.         }
  653.         else
  654.         Dipxe(bug("X=%d is not asocciated with a Window\n",
  655.             event.xany.window));
  656.  
  657.         UnlockIBase (lock);
  658.  
  659.         if (!w)
  660.         continue;
  661.  
  662.         gi->gi_Screen      = screen;
  663.         gi->gi_Window      = w;
  664.         gi->gi_Domain      = *((struct IBox *)&w->LeftEdge);
  665.         gi->gi_RastPort      = w->RPort;
  666.         gi->gi_Pens.DetailPen = gi->gi_Screen->DetailPen;
  667.         gi->gi_Pens.BlockPen  = gi->gi_Screen->BlockPen;
  668.         gi->gi_DrInfo      = &(((struct IntScreen *)screen)->DInfo);
  669.  
  670.         iw = (struct IntWindow *)w;
  671.  
  672.         if (!im)
  673.         im = AllocMem (sizeof (struct IntuiMessage), MEMF_CLEAR);
  674.  
  675.         im->Class        = 0L;
  676.         im->IDCMPWindow = w;
  677.         im->MouseX        = mpos_x;
  678.         im->MouseY        = mpos_y;
  679.  
  680.         switch (event.type)
  681.         {
  682.         case GraphicsExpose:
  683.         case Expose: {
  684.         XRectangle rect;
  685.         UWORD       count;
  686.  
  687.         if (event.type == Expose)
  688.         {
  689.             rect.x    = event.xexpose.x;
  690.             rect.y    = event.xexpose.y;
  691.             rect.width    = event.xexpose.width;
  692.             rect.height = event.xexpose.height;
  693.             count    = event.xexpose.count;
  694.         }
  695.         else
  696.         {
  697.             rect.x    = event.xgraphicsexpose.x;
  698.             rect.y    = event.xgraphicsexpose.y;
  699.             rect.width    = event.xgraphicsexpose.width;
  700.             rect.height = event.xgraphicsexpose.height;
  701.             count    = event.xgraphicsexpose.count;
  702.         }
  703.  
  704.         XUnionRectWithRegion (&rect, iw->iw_Region, iw->iw_Region);
  705.  
  706.         if (count != 0)
  707.             break;
  708.  
  709.         RefreshGadgets (w->FirstGadget, w, NULL);
  710.  
  711.         im->Class = IDCMP_REFRESHWINDOW;
  712.         ptr      = "REFRESHWINDOW";
  713.         } break;
  714.  
  715.         case ConfigureNotify:
  716.         if (w->Width != event.xconfigure.width ||
  717.             w->Height != event.xconfigure.height)
  718.         {
  719.             w->Width  = event.xconfigure.width;
  720.             w->Height = event.xconfigure.height;
  721.  
  722.             im->Class = NEWSIZE;
  723.             ptr       = "NEWSIZE";
  724.         }
  725.  
  726.         break;
  727.  
  728.         case ButtonPress: {
  729.         XButtonEvent * xb = &event.xbutton;
  730.  
  731.         im->Class = MOUSEBUTTONS;
  732.         im->Qualifier = StateToQualifier (xb->state);
  733.         im->MouseX = xb->x;
  734.         im->MouseY = xb->y;
  735.  
  736.         switch (xb->button)
  737.         {
  738.         case Button1:
  739.             im->Code = SELECTDOWN;
  740.  
  741.             gadget = FindGadget (w, xb->x, xb->y, gi);
  742.  
  743.             if (gadget)
  744.             {
  745.             if (gadget->Activation & GACT_IMMEDIATE)
  746.             {
  747.                 im->Class = GADGETDOWN;
  748.                 im->IAddress = gadget;
  749.                 ptr       = "GADGETDOWN";
  750.             }
  751.  
  752.             switch (gadget->GadgetType & GTYP_GTYPEMASK)
  753.             {
  754.             case GTYP_BOOLGADGET:
  755.                 if (gadget->Activation & GACT_TOGGLESELECT)
  756.                 gadget->Flags ^= GFLG_SELECTED;
  757.                 else
  758.                 gadget->Flags |= GFLG_SELECTED;
  759.  
  760.                 RefreshGList (gadget, w, NULL, 1);
  761.  
  762.                 break;
  763.  
  764.             case GTYP_PROPGADGET: {
  765.                 struct BBox knob;
  766.                 struct PropInfo * pi;
  767.                 UWORD dx, dy, flags;
  768.  
  769.                 pi = (struct PropInfo *)gadget->SpecialInfo;
  770.  
  771.                 if (!pi)
  772.                 break;
  773.  
  774.                 CalcBBox (w, gadget, &knob);
  775.  
  776.                 if (!CalcKnobSize (gadget, &knob))
  777.                 break;
  778.  
  779.                 dx = pi->HorizPot;
  780.                 dy = pi->VertPot;
  781.  
  782.                 if (pi->Flags & FREEHORIZ)
  783.                 {
  784.                 if (xb->x < knob.Left)
  785.                 {
  786.                     if (dx > pi->HPotRes)
  787.                     dx -= pi->HPotRes;
  788.                     else
  789.                     dx = 0;
  790.                 }
  791.                 else if (xb->x >= knob.Left + knob.Width)
  792.                 {
  793.                     if (dx + pi->HPotRes < MAXPOT)
  794.                     dx += pi->HPotRes;
  795.                     else
  796.                     dx = MAXPOT;
  797.                 }
  798.                 }
  799.  
  800.                 if (pi->Flags & FREEVERT)
  801.                 {
  802.                 if (xb->y < knob.Top)
  803.                 {
  804.                     if (dy > pi->VPotRes)
  805.                     dy -= pi->VPotRes;
  806.                     else
  807.                     dy = 0;
  808.                 }
  809.                 else if (xb->y >= knob.Top + knob.Height)
  810.                 {
  811.                     if (dy + pi->VPotRes < MAXPOT)
  812.                     dy += pi->VPotRes;
  813.                     else
  814.                     dy = MAXPOT;
  815.                 }
  816.                 }
  817.  
  818.                 flags = pi->Flags;
  819.  
  820.                 if (xb->x >= knob.Left
  821.                 && xb->y >= knob.Top
  822.                 && xb->x < knob.Left + knob.Width
  823.                 && xb->y < knob.Top + knob.Height
  824.                 )
  825.                 flags |= KNOBHIT;
  826.                 else
  827.                 flags &= ~KNOBHIT;
  828.  
  829.                 gadget->Flags |= GFLG_SELECTED;
  830.  
  831.                 NewModifyProp (gadget
  832.                 , w
  833.                 , NULL
  834.                 , flags
  835.                 , dx
  836.                 , dy
  837.                 , pi->HorizBody
  838.                 , pi->VertBody
  839.                 , 1
  840.                 );
  841.  
  842.                 break; }
  843.  
  844.             case GTYP_CUSTOMGADGET: {
  845.                 struct gpInput gpi;
  846.                 struct InputEvent ie; /* TODO */
  847.                 IPTR retval;
  848.                 ULONG termination;
  849.  
  850.                 ie.ie_Class = IECLASS_RAWMOUSE;
  851.                 ie.ie_Code    = SELECTDOWN;
  852.  
  853.                 gpi.MethodID    = GM_GOACTIVE;
  854.                 gpi.gpi_GInfo    = gi;
  855.                 gpi.gpi_IEvent    = &ie;
  856.                 gpi.gpi_Termination = &termination;
  857.                 gpi.gpi_Mouse.X    = xb->x;
  858.                 gpi.gpi_Mouse.Y    = xb->y;
  859.                 gpi.gpi_TabletData    = NULL;
  860.  
  861.                 retval = DoMethodA ((Object *)gadget, (Msg)&gpi);
  862.  
  863.                 if (retval != GMR_MEACTIVE)
  864.                 {
  865.                 im->Class = 0L;
  866.                 gadget = NULL;
  867.                 }
  868.  
  869.                 break; }
  870.  
  871.             } /* GadgetType */
  872.             } /* Over some gadget ? */
  873.  
  874.             break;
  875.  
  876.         case Button2:
  877.             im->Code = MIDDLEDOWN;
  878.             break;
  879.  
  880.         case Button3:
  881.             im->Code = MENUDOWN;
  882.             break;
  883.         }
  884.  
  885.         if (im->Class == MOUSEBUTTONS)
  886.             ptr = "MOUSEBUTTONS";
  887.         } break;
  888.  
  889.         case ButtonRelease: {
  890.         XButtonEvent * xb = &event.xbutton;
  891.  
  892.         im->Class = MOUSEBUTTONS;
  893.         im->Qualifier = StateToQualifier (xb->state);
  894.         im->MouseX = xb->x;
  895.         im->MouseY = xb->y;
  896.  
  897.         switch (xb->button)
  898.         {
  899.         case Button1:
  900.             im->Code = SELECTUP;
  901.  
  902.             if (gadget)
  903.             {
  904.             int inside = InsideGadget(w,gadget,xb->x,xb->y);
  905.             int selected = (gadget->Flags & GFLG_SELECTED) != 0;
  906.  
  907.             if (inside && (gadget->Activation & GACT_RELVERIFY))
  908.             {
  909.                 im->Class = GADGETUP;
  910.                 im->IAddress = gadget;
  911.                 ptr       = "GADGETDOWN";
  912.             }
  913.  
  914.             switch (gadget->GadgetType & GTYP_GTYPEMASK)
  915.             {
  916.             case GTYP_BOOLGADGET:
  917.                 if (!(gadget->Activation & GACT_TOGGLESELECT) )
  918.                 gadget->Flags &= ~GFLG_SELECTED;
  919.  
  920.                 if (selected)
  921.                 RefreshGList (gadget, w, NULL, 1);
  922.  
  923.                 break;
  924.  
  925.             case GTYP_PROPGADGET: {
  926.                 struct PropInfo * pi;
  927.  
  928.                 pi = (struct PropInfo *)gadget->SpecialInfo;
  929.  
  930.                 gadget->Flags &= ~GFLG_SELECTED;
  931.  
  932.                 if (pi)
  933.                 NewModifyProp (gadget
  934.                     , w
  935.                     , NULL
  936.                     , pi->Flags &= ~KNOBHIT
  937.                     , pi->HorizPot
  938.                     , pi->VertPot
  939.                     , pi->HorizBody
  940.                     , pi->VertBody
  941.                     , 1
  942.                 );
  943.  
  944.                 break; }
  945.  
  946.             case GTYP_CUSTOMGADGET: {
  947.                 struct gpInput gpi;
  948.                 struct InputEvent ie; /* TODO */
  949.                 IPTR retval;
  950.                 ULONG termination;
  951.  
  952.                 ie.ie_Class = IECLASS_RAWMOUSE;
  953.                 ie.ie_Code    = SELECTUP;
  954.  
  955.                 gpi.MethodID    = GM_HANDLEINPUT;
  956.                 gpi.gpi_GInfo    = gi;
  957.                 gpi.gpi_IEvent    = &ie;
  958.                 gpi.gpi_Termination = &termination;
  959.                 gpi.gpi_Mouse.X    = xb->x;
  960.                 gpi.gpi_Mouse.Y    = xb->y;
  961.                 gpi.gpi_TabletData    = NULL;
  962.  
  963.                 retval = DoMethodA ((Object *)gadget, (Msg)&gpi);
  964.  
  965.                 if (retval & GMR_NOREUSE && !(retval & GMR_VERIFY))
  966.                 im->Class = 0L; /* Swallow event */
  967.  
  968.                 break; }
  969.  
  970.             } /* switch GadgetType */
  971.  
  972.             gadget = NULL;
  973.             } /* if (gadget) */
  974.  
  975.             break;
  976.  
  977.         case Button2:
  978.             im->Code = MIDDLEUP;
  979.             break;
  980.  
  981.         case Button3:
  982.             im->Code = MENUUP;
  983.             break;
  984.         }
  985.  
  986.         ptr = "MOUSEBUTTONS";
  987.         } break;
  988.  
  989.         case KeyPress: {
  990.         XKeyEvent * xk = &event.xkey;
  991.         ULONG result;
  992.  
  993.         im->Class = RAWKEY;
  994.         result = XKeyToAmigaCode(xk);
  995.         im->Code = xk->keycode;
  996.         im->Qualifier = result >> 16;
  997.  
  998.         ptr = NULL;
  999.         } break;
  1000.  
  1001.         case KeyRelease: {
  1002.         XKeyEvent * xk = &event.xkey;
  1003.         ULONG result;
  1004.  
  1005.         im->Class = RAWKEY;
  1006.         result = XKeyToAmigaCode(xk);
  1007.         im->Code = xk->keycode | 0x8000;
  1008.         im->Qualifier = result >> 16;
  1009.  
  1010.         ptr = NULL;
  1011.         } break;
  1012.  
  1013.         case MotionNotify: {
  1014.         XMotionEvent * xm = &event.xmotion;
  1015.  
  1016.         im->Code = IECODE_NOBUTTON;
  1017.         im->Class = MOUSEMOVE;
  1018.         im->Qualifier = StateToQualifier (xm->state);
  1019.         im->MouseX = xm->x;
  1020.         im->MouseY = xm->y;
  1021.  
  1022.         if (gadget)
  1023.         {
  1024.             int inside = InsideGadget(w,gadget,xm->x,xm->y);
  1025.             int selected = (gadget->Flags & GFLG_SELECTED) != 0;
  1026.  
  1027.             switch (gadget->GadgetType & GTYP_GTYPEMASK)
  1028.             {
  1029.             case GTYP_BOOLGADGET:
  1030.             if (inside != selected)
  1031.             {
  1032.                 gadget->Flags ^= GFLG_SELECTED;
  1033.  
  1034.                 RefreshGList (gadget, w, NULL, 1);
  1035.             }
  1036.  
  1037.             break;
  1038.  
  1039.             case GTYP_PROPGADGET: {
  1040.             struct BBox knob;
  1041.             long dx, dy;
  1042.             struct PropInfo * pi;
  1043.  
  1044.             pi = (struct PropInfo *)gadget->SpecialInfo;
  1045.  
  1046.             /* Has propinfo and the mouse was over the
  1047.                 knob */
  1048.             if (pi && (pi->Flags & KNOBHIT))
  1049.             {
  1050.                 CalcBBox (w, gadget, &knob);
  1051.  
  1052.                 if (!CalcKnobSize (gadget, &knob))
  1053.                 break;
  1054.  
  1055.                 /* Delta movement */
  1056.                 dx = xm->x - mpos_x;
  1057.                 dy = xm->y - mpos_y;
  1058.  
  1059.                 /* Move the knob the same amount, ie.
  1060.                 knob.Left += dx; knob.Top += dy;
  1061.  
  1062.                 knob.Left = knob.Left
  1063.                     + (pi->CWidth - knob.Width)
  1064.                     * pi->HorizPot / MAXPOT;
  1065.  
  1066.                 ie. dx = (pi->CWidth - knob.Width)
  1067.                     * pi->HorizPot / MAXPOT;
  1068.  
  1069.                 or
  1070.  
  1071.                 pi->HorizPot = (dx * MAXPOT) /
  1072.                     (pi->CWidth - knob.Width);
  1073.                 */
  1074.                 if (pi->Flags & FREEHORIZ
  1075.                 && pi->CWidth != knob.Width)
  1076.                 {
  1077.                 dx = (dx * MAXPOT) /
  1078.                     (pi->CWidth - knob.Width);
  1079.  
  1080.                 if (dx < 0)
  1081.                 {
  1082.                     dx = -dx;
  1083.  
  1084.                     if (dx > pi->HorizPot)
  1085.                     dx = 0;
  1086.                     else
  1087.                     dx = pi->HorizPot - dx;
  1088.                 }
  1089.                 else
  1090.                 {
  1091.                     if (dx + pi->HorizPot > MAXPOT)
  1092.                     dx = MAXPOT;
  1093.                     else
  1094.                     dx = pi->HorizPot + dx;
  1095.                 }
  1096.                 } /* FREEHORIZ */
  1097.  
  1098.                 if (pi->Flags & FREEVERT
  1099.                 && pi->CHeight != knob.Height)
  1100.                 {
  1101.                 dy = (dy * MAXPOT) /
  1102.                     (pi->CHeight - knob.Height);
  1103.  
  1104.                 if (dy < 0)
  1105.                 {
  1106.                     dy = -dy;
  1107.  
  1108.                     if (dy > pi->VertPot)
  1109.                     dy = 0;
  1110.                     else
  1111.                     dy = pi->VertPot - dy;
  1112.                 }
  1113.                 else
  1114.                 {
  1115.                     if (dy + pi->VertPot > MAXPOT)
  1116.                     dy = MAXPOT;
  1117.                     else
  1118.                     dy = pi->VertPot + dy;
  1119.                 }
  1120.                 } /* FREEVERT */
  1121.             } /* Has PropInfo and Mouse is over knob */
  1122.  
  1123.             NewModifyProp (gadget
  1124.                 , w
  1125.                 , NULL
  1126.                 , pi->Flags
  1127.                 , dx
  1128.                 , dy
  1129.                 , pi->HorizBody
  1130.                 , pi->VertBody
  1131.                 , 1
  1132.             );
  1133.  
  1134.             break; } /* PROPGADGET */
  1135.  
  1136.             case GTYP_CUSTOMGADGET: {
  1137.             struct gpInput gpi;
  1138.             struct InputEvent ie; /* TODO */
  1139.             IPTR retval;
  1140.             ULONG termination;
  1141.  
  1142.             ie.ie_Class = IECLASS_RAWMOUSE;
  1143.             ie.ie_Code  = IECODE_NOBUTTON;
  1144.  
  1145.             gpi.MethodID        = GM_HANDLEINPUT;
  1146.             gpi.gpi_GInfo        = gi;
  1147.             gpi.gpi_IEvent        = &ie;
  1148.             gpi.gpi_Termination = &termination;
  1149.             gpi.gpi_Mouse.X     = xm->x;
  1150.             gpi.gpi_Mouse.Y     = xm->y;
  1151.             gpi.gpi_TabletData  = NULL;
  1152.  
  1153.             retval = DoMethodA ((Object *)gadget, (Msg)&gpi);
  1154.  
  1155.             if (retval == GMR_MEACTIVE)
  1156.             {
  1157.                 im->Class = 0L;
  1158.             }
  1159.  
  1160.             if (retval & GMR_NOREUSE)
  1161.                 im->Class = 0L; /* Swallow event */
  1162.  
  1163.             break; }
  1164.  
  1165.             } /* switch GadgetType */
  1166.         } /* if (gadget) */
  1167.  
  1168.         ptr = "MOUSEMOVE";
  1169.         } break; /* MotioNotify */
  1170.  
  1171.         case EnterNotify: {
  1172.         XCrossingEvent * xc = &event.xcrossing;
  1173.  
  1174.         im->Class = ACTIVEWINDOW;
  1175.         im->MouseX = xc->x;
  1176.         im->MouseY = xc->y;
  1177.  
  1178.         ptr = "ACTIVEWINDOW";
  1179.         } break;
  1180.  
  1181.         case LeaveNotify: {
  1182.         XCrossingEvent * xc = &event.xcrossing;
  1183.  
  1184.         im->Class = ACTIVEWINDOW;
  1185.         im->MouseX = xc->x;
  1186.         im->MouseY = xc->y;
  1187.  
  1188.         ptr = "INACTIVEWINDOW";
  1189.         } break;
  1190.  
  1191.         default:
  1192.         ptr = NULL;
  1193.         break;
  1194.         } /* switch */
  1195.  
  1196.         mpos_x = im->MouseX;
  1197.         mpos_y = im->MouseY;
  1198.  
  1199.         if (ptr)
  1200.         Dipxe(bug("Msg=%s\n", ptr));
  1201.  
  1202.         if (im->Class)
  1203.         {
  1204.         if ((im->Class & w->IDCMPFlags) && w->UserPort)
  1205.         {
  1206.             im->ExecMessage.mn_ReplyPort = intuiReplyPort;
  1207.  
  1208.             lock = LockIBase (0L);
  1209.  
  1210.             w->MoreFlags &= ~EWFLG_DELAYCLOSE;
  1211.  
  1212.             if (w->MoreFlags & EWFLG_CLOSEWINDOW)
  1213.             CloseWindow (w);
  1214.             else
  1215.             {
  1216.             PutMsg (w->UserPort, (struct Message *)im);
  1217.             im = NULL;
  1218.             wait ++;
  1219.             }
  1220.  
  1221.             UnlockIBase (lock);
  1222.         }
  1223.         else
  1224.             im->Class = 0;
  1225.         }
  1226.     }
  1227.  
  1228.     if (im)
  1229.         FreeMem (im, sizeof (struct IntuiMessage));
  1230.  
  1231.     Wait (1L << intuiReplyPort->mp_SigBit | SIGBREAKF_CTRL_F);
  1232.  
  1233.     /* Empty port */
  1234.     while ((im = (struct IntuiMessage *)GetMsg (intuiReplyPort)))
  1235.     {
  1236.         FreeMem (im, sizeof (struct IntuiMessage));
  1237.         wait --;
  1238.     }
  1239.     }
  1240. }
  1241.  
  1242.